<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <link rel="shortcut icon" href="img/favicon.ico">
  <title>Atomic - Java Note</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700" />

  <link rel="stylesheet" href="css/theme.css" />
  <link rel="stylesheet" href="css/theme_extra.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
  
  <script>
    // Current page data
    var mkdocs_page_name = "Atomic";
    var mkdocs_page_input_path = "Atomic.md";
    var mkdocs_page_url = null;
  </script>
  
  <script src="js/jquery-2.1.1.min.js" defer></script>
  <script src="js/modernizr-2.8.3.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script> 
  
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
        <a href="." class="icon icon-home"> Java Note</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="./search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="index.html">Home</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="StringX.html">StringX</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Collection.html">Collection</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="IO.html">IOFile</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Lambda.html">Lambda</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Generic.html">Generic</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Stream.html">Stream</a>
                    </li>
                </ul>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="Atomic.html">Atomic</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#_1">原子操作类</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#example">example</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#ai">AI</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#aia">AIA</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#ar">AR</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#aifu">AIFU</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#trandition">trandition</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#conception">Conception</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#_2">悲观锁</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#_3">乐观锁</a>
        <ul>
    <li class="toctree-l4"><a class="reference internal" href="#versionnumber">VersionNumber</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#cas">CAS</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#aba">ABA 问题</a>
    </li>
        </ul>
    </li>
        </ul>
    </li>
    </ul>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Reflect.html">Reflect</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="JavaFX.html">JavaFX</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Sundry.html">Sundry</a>
                    </li>
                </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href=".">Java Note</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href=".">Docs</a> &raquo;</li>
    
      
    
    <li>Atomic</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h2 id="atomic">Atomic</h2>
<h3 id="_1">原子操作类</h3>
<blockquote>
<p><code>java.util.concurrent.atomic</code></p>
</blockquote>
<p>一系列 <code>Atomic</code> 开头的类 13个类 4种类型</p>
<ol>
<li>基本类型<ol>
<li><code>AtomicBoolean</code></li>
<li><a href="#AI"><code>AtomicInteger</code></a></li>
<li><code>AtomicLong</code></li>
</ol>
</li>
<li>数组类<ol>
<li><a href="#AIA"><code>AtomicIntegerArray</code></a></li>
<li><code>AtomicLongArray</code></li>
<li><code>AtomicReferenceArray</code><ol>
<li>更新引用数组的元素</li>
</ol>
</li>
</ol>
</li>
<li>引用类型<ol>
<li><a href="#AR"><code>AtomicReference</code></a></li>
<li><code>AtomicReferenceFieldUpdater</code><ol>
<li>更新引用类型中的字段</li>
</ol>
</li>
<li><code>AtomicMarkableReference</code><ol>
<li>原子更新带有标记位的引用类型</li>
<li>可以原子的更新一个布尔类型的标记位和引用类型</li>
<li>构造方法是<code>AtomicMarkableReference(V initialRef, boolean initialMark)</code></li>
</ol>
</li>
</ol>
</li>
<li>字段类(<strong>Abstract</strong>)<ol>
<li><a href="#AIFU"><code>AtomicIntegerFieldUpdater</code></a></li>
<li><code>AtomicLongFieldUpdater</code></li>
<li><code>AtomicStampedReference</code></li>
<li>每次使用都时候必须使用静态方法<code>newUpdater</code>创建一个更新器</li>
<li>字段必须为 <code>public volatile</code> </li>
</ol>
</li>
</ol>
<h4 id="example">example</h4>
<h4 id="ai">AI</h4>
<pre><code class="language-java">AtomicInteger // as an example

// 以原子方式将给定值与当前值相加  可用于线程中的计数使用  （返回更新的值）。
int addAndGet(int delta);

// 以原子方式将给定值与当前值相加  可用于线程中的计数使用  （返回以前的值）
int getAndAdd(int delta);

// 以原子方式将当前值加 1（返回更新的值）
int incrementAndGet();

// 以原子方式将当前值加 1（返回以前的值）
int getAndIncrement();

// 以原子方式设置为给定值（返回旧值）
int getAndSet(int newValue);

// 以原子方式将当前值减 1（返回更新的值）
int decrementAndGet();

// 以原子方式将当前值减 1（返回以前的值）
int getAndDecrement();

// 获取当前值
int get();

// 设置当前值
void set(int);
</code></pre>
<h4 id="aia">AIA</h4>
<pre><code class="language-java">public class AtomicIntegerArrayTest {

    static int[] value = new int[] { 1, 2 };

    static AtomicIntegerArray ai = new AtomicIntegerArray(value);

    public static void main(String[] args) {
        ai.getAndSet(0, 3);
        System.out.println(ai.get(0));
        System.out.println(value[0]);
    }

}
</code></pre>
<h4 id="ar">AR</h4>
<pre><code class="language-java">public class AtomicReferenceTest {

    public static AtomicReference&lt;user&gt; atomicUserRef = new AtomicReference&lt;user&gt;();

    public static void main(String[] args) {
        User user = new User(&quot;conan&quot;, 15);
        atomicUserRef.set(user);
        User updateUser = new User(&quot;Shinichi&quot;, 17);
        atomicUserRef.compareAndSet(user, updateUser);
        System.out.println(atomicUserRef.get().getName());
        System.out.println(atomicUserRef.get().getOld());
    }

    static class User {
        private String name;
        private int old;

        public User(String name, int old) {
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public int getOld() {
            return old;
        }
    }
}
</code></pre>
<h4 id="aifu">AIFU</h4>
<pre><code class="language-java">public class AtomicIntegerFieldUpdaterTest {

    private static AtomicIntegerFieldUpdater&lt;User&gt; a = AtomicIntegerFieldUpdater
            .newUpdater(User.class, &quot;old&quot;);

    public static void main(String[] args) {
        User conan = new User(&quot;conan&quot;, 10);
        System.out.println(a.getAndIncrement(conan));
        System.out.println(a.get(conan));
    }

    public static class User {
        private String name;
        public volatile int old;

        public User(String name, int old) {
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public int getOld() {
            return old;
        }
    }
}
</code></pre>
<h3 id="trandition">trandition</h3>
<blockquote>
<p><code>synchronized</code> 线程锁</p>
</blockquote>
<pre><code class="language-java">class Count{

    // 共享变量
    private Integer count = 0;
    public Integer getCount() {
        return count;
    }
    public  void increase() {//public synchronized void increas(){//for thread safe
        count++;
    }
}
</code></pre>
<pre><code class="language-java">public class AtomicMain {

    public static void main(String[] args) throws InterruptedException {

        ExecutorService service = Executors.newCachedThreadPool();

        Count count = new Count();
        // 100个线程对共享变量进行加1
        for (int i = 0; i &lt; 100; i++) {
            service.execute(() -&gt; count.increase());
        }

        // 等待上述的线程执行完
        service.shutdown();
        service.awaitTermination(1, TimeUnit.DAYS);


        System.out.println(&quot;公众号 : Java3y---------&quot;);
        System.out.println(count.getCount());
    }

}
</code></pre>
<h3 id="conception">Conception</h3>
<h4 id="_2">悲观锁</h4>
<blockquote>
<p>总是假设最坏的情况 每次去读取数据时总认为别人会修改 因此每次读取数据时都会上锁 其他线程想访问该数据时只能阻塞 直到这个线程释放了锁</p>
</blockquote>
<p>如 <code>synchronized</code>   <code>ReentrantLock</code> </p>
<p>适用于 <strong>多写</strong> 的场景</p>
<h4 id="_3">乐观锁</h4>
<blockquote>
<p>总是假设最好的情况 每次去读取数据时总认为别人不会修改 因此每次读取数据时不会上锁 但是在做写操作时会判断一下从读取这个数据到真正执行写操作前有没有其他线程去更新这个数据</p>
</blockquote>
<p>常用实现</p>
<ol>
<li><a href="#VersionNumber">版本号机制</a></li>
<li><a href="#CAS"><code>CAS</code></a> 算法实现<ol>
<li><code>Atomic</code></li>
</ol>
</li>
</ol>
<p>适用于 <strong>多读</strong> 场景</p>
<h5 id="versionnumber">VersionNumber</h5>
<p>在数据库表中加一个版本号字段 : version_id  当数据被修改时  版本号会+1。当从数据库读取数据时  记录此时的版本号version_id1  在对数据进行写操作时  再从当前数据库里读取版本号 : version_id2  若此时 <strong>version_id1 == version_id2</strong>  即认为从读到这个数据到更新这个数据之间该数据没有被更新  此时更新数据；反之  重试更新操作直到成功 </p>
<h5 id="cas">CAS</h5>
<blockquote>
<p>Compare And Swap</p>
</blockquote>
<p>三个基本操作数</p>
<ol>
<li>内存地址 <strong>V</strong></li>
<li>旧的预期值 <strong>A</strong></li>
<li>要修改的新值 <strong>B</strong></li>
</ol>
<pre><code class="language-C++">bool CAS = false;//大致示意图
while(! CAS){
    if ( A == *V ){
        *V = B;
        CAS = true;
    }
    else{// 自旋
        // 重新计算值
        A = Cal(A);
        B = Cal(B);
    }
}
</code></pre>
<h5 id="aba">ABA 问题</h5>
<blockquote>
<p><code>AtomicStampedReference</code>原子类是一个带有时间戳的对象引用  在每次修改后</p>
<p><code>AtomicStampedReference</code>不仅会设置新值而且还会记录更改的时间 </p>
<p>当<code>AtomicStampedReference</code>设置对象值时 对象值以及时间戳都必须满足期望值才能写入成功 这也就解决了反复读写时 无法预知值是否已被修改的窘境</p>
</blockquote>
              
            </div>
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="Reflect.html" class="btn btn-neutral float-right" title="Reflect">Next <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="Stream.html" class="btn btn-neutral" title="Stream"><span class="icon icon-circle-arrow-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
    
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
      
        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      
      
        <span><a href="Stream.html" style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="Reflect.html" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>
    <script>var base_url = '.';</script>
    <script src="js/theme.js" defer></script>
      <script src="search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
